﻿namespace eeenno.SpeeedReaderUI.NativeWebBrowser.Runtime.InteropServices
{
    using System;
    using System.Collections;
    using System.IO;
    using System.Text;

    public class MarshallingMethods
    {
        public static Hashtable ReadMethods = new Hashtable();
        public static Hashtable WriteMethods = new Hashtable();

        static MarshallingMethods()
        {
            ReadMethods.Add(typeof(bool), typeof(BinaryReader).GetMethod("ReadBoolean"));
            ReadMethods.Add(typeof(byte), typeof(BinaryReader).GetMethod("ReadByte"));
            ReadMethods.Add(typeof(sbyte), typeof(BinaryReader).GetMethod("ReadSByte"));
            ReadMethods.Add(typeof(float), typeof(BinaryReader).GetMethod("ReadSingle"));
            ReadMethods.Add(typeof(byte[]), typeof(BinaryReader).GetMethod("ReadBytes"));
            ReadMethods.Add(typeof(char[]), typeof(BinaryReader).GetMethod("ReadChars"));
            ReadMethods.Add(typeof(short), typeof(BinaryReader).GetMethod("ReadInt16"));
            ReadMethods.Add(typeof(int), typeof(BinaryReader).GetMethod("ReadInt32"));
            ReadMethods.Add(typeof(ushort), typeof(BinaryReader).GetMethod("ReadUInt16"));
            ReadMethods.Add(typeof(uint), typeof(BinaryReader).GetMethod("ReadUInt32"));
            ReadMethods.Add(typeof(string), typeof(MarshallingMethods).GetMethod("ReadString"));
            ReadMethods.Add(typeof(DateTime), typeof(MarshallingMethods).GetMethod("ReadDateTime"));
            ReadMethods.Add(typeof(short[]), typeof(MarshallingMethods).GetMethod("ReadInt16Array"));
            ReadMethods.Add(typeof(int[]), typeof(MarshallingMethods).GetMethod("ReadInt32Array"));
            ReadMethods.Add(typeof(ushort[]), typeof(MarshallingMethods).GetMethod("ReadUInt16Array"));
            ReadMethods.Add(typeof(uint[]), typeof(MarshallingMethods).GetMethod("ReadUInt32Array"));
            ReadMethods.Add(typeof(AdvancedMarshaler), typeof(AdvancedMarshaler).GetMethod("ReadFromStream"));
            WriteMethods.Add(typeof(bool), typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }));
            WriteMethods.Add(typeof(byte), typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(byte) }));
            WriteMethods.Add(typeof(sbyte), typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(sbyte) }));
            WriteMethods.Add(typeof(float), typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(float) }));
            WriteMethods.Add(typeof(short), typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(short) }));
            WriteMethods.Add(typeof(int), typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(int) }));
            WriteMethods.Add(typeof(ushort), typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(ushort) }));
            WriteMethods.Add(typeof(uint), typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(uint) }));
            WriteMethods.Add(typeof(string), typeof(MarshallingMethods).GetMethod("WriteString"));
            WriteMethods.Add(typeof(AdvancedMarshaler), typeof(AdvancedMarshaler).GetMethod("WriteToStream"));
            WriteMethods.Add(typeof(byte[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(byte[]) }));
            WriteMethods.Add(typeof(bool[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(bool[]) }));
            WriteMethods.Add(typeof(char[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(char[]) }));
            WriteMethods.Add(typeof(short[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(short[]) }));
            WriteMethods.Add(typeof(ushort[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(ushort[]) }));
            WriteMethods.Add(typeof(int[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(int[]) }));
            WriteMethods.Add(typeof(uint[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(uint[]) }));
            WriteMethods.Add(typeof(long[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(long[]) }));
            WriteMethods.Add(typeof(ulong[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(ulong[]) }));
            WriteMethods.Add(typeof(float[]), typeof(MarshallingMethods).GetMethod("WriteArray", new Type[] { typeof(BinaryWriter), typeof(float[]) }));
        }

        public static DateTime ReadDateTime(BinaryReader reader)
        {
            return DateTime.FromFileTime(reader.ReadInt64());
        }

        public static short[] ReadInt16Array(BinaryReader reader, int count)
        {
            short[] numArray = new short[count];
            for (int i = 0; i < count; i++)
            {
                numArray[i] = reader.ReadInt16();
            }
            return numArray;
        }

        public static int[] ReadInt32Array(BinaryReader reader, int count)
        {
            int[] numArray = new int[count];
            for (int i = 0; i < count; i++)
            {
                numArray[i] = reader.ReadInt32();
            }
            return numArray;
        }

        public static string ReadString(BinaryReader reader, int count)
        {
            if (count == 0)
            {
                count = 0xff;
            }
            return new string(reader.ReadChars(count)).TrimEnd(new char[1]);
        }

        [CLSCompliant(false)]
        public static ushort[] ReadUInt16Array(BinaryReader reader, int count)
        {
            ushort[] numArray = new ushort[count];
            for (int i = 0; i < count; i++)
            {
                numArray[i] = reader.ReadUInt16();
            }
            return numArray;
        }

        [CLSCompliant(false)]
        public static uint[] ReadUInt32Array(BinaryReader reader, int count)
        {
            uint[] numArray = new uint[count];
            for (int i = 0; i < count; i++)
            {
                numArray[i] = reader.ReadUInt32();
            }
            return numArray;
        }

        public static void WriteArray(BinaryWriter writer, bool[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        public static void WriteArray(BinaryWriter writer, byte[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        public static void WriteArray(BinaryWriter writer, char[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        public static void WriteArray(BinaryWriter writer, short[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        public static void WriteArray(BinaryWriter writer, int[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        public static void WriteArray(BinaryWriter writer, long[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        public static void WriteArray(BinaryWriter writer, float[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        [CLSCompliant(false)]
        public static void WriteArray(BinaryWriter writer, ushort[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        [CLSCompliant(false)]
        public static void WriteArray(BinaryWriter writer, uint[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        [CLSCompliant(false)]
        public static void WriteArray(BinaryWriter writer, ulong[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                writer.Write(arr[i]);
            }
        }

        public static void WriteSerializers(BinaryWriter writer, AdvancedMarshaler[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i].WriteToStream(writer);
            }
        }

        public static void WriteString(BinaryWriter writer, string value, int size)
        {
            if (value != null)
            {
                byte[] bytes = Encoding.Unicode.GetBytes(value.Substring(0, size));
                writer.Write(bytes);
            }
        }
    }
}

